package cn.itcast.account.service.impl;

import cn.itcast.account.entity.AccountFreeze;
import cn.itcast.account.mapper.AccountFreezeMapper;
import cn.itcast.account.mapper.AccountMapper;
import cn.itcast.account.service.AccountTCCService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * ClassName: AccountTCCServiceImpl
 * Package: cn.itcast.account.service.impl
 * Description:
 *
 * @Author 梓维李
 * @Create 2023/4/6 13:32
 * @Version 2.0
 */
@Service
@Slf4j
public class AccountTCCServiceImpl extends ServiceImpl<AccountFreezeMapper, AccountFreeze> implements AccountTCCService{

    @Autowired
    private AccountMapper accountMapper ;

    @Autowired
    private AccountFreezeMapper accountFreezeMapper ;

    @Override
    @Transactional
    public void deduct(String userId, int money) {    //try方法

        //获取全局事务id
        String xid = RootContext.getXID();
        //判断freeze中是否有冻结记录，如果有，那么一定是cancel执行过，拒绝该业务
        if (accountFreezeMapper.selectById(xid) != null){
            //说明cancel执行过   打回
            return  ;
        }
        //扣减可用余额
        accountMapper.deduct(userId,money) ;
        //冻结金额
        AccountFreeze accountFreeze = new AccountFreeze() ;
        accountFreeze.setXid(xid);
        accountFreeze.setFreezeMoney(money);
        accountFreeze.setState(0);
        accountFreeze.setUserId(userId);
        //新增数据
        int insert = accountFreezeMapper.insert(accountFreeze);
        System.out.println(insert);
    }

    @Override
    public boolean confirm(BusinessActionContext context) {
        //获取事务id
        String xid = context.getXid();
        //执行删除功能
        int i = accountFreezeMapper.deleteById(xid);
        System.out.println("进入到confirm==============");
        return true;
    }

    @Override
    public boolean cancel(BusinessActionContext context) {
        //拿到事务id
        String xid = context.getXid();
        //拿到方法参数
        String userId = context.getActionContext("userId").toString();
        //执行逻辑与try相反，失败回滚才走到这
        //根据id查询记录
        AccountFreeze accountFreeze = accountFreezeMapper.selectById(xid);
        //进行空回滚的判断
        if (accountFreeze == null){
            //说明try没执行，空回滚
            //插入数据，记录空回滚
            AccountFreeze accountFreeze1 = new AccountFreeze() ;
            accountFreeze1.setXid(xid);
            accountFreeze1.setUserId(userId);
            accountFreeze1.setState(AccountFreeze.State.CANCEL);
            accountFreeze1.setFreezeMoney(0);
            accountFreezeMapper.insert(accountFreeze1);
            return true;
        }
        //幂等处理
        if (accountFreeze.getState() == AccountFreeze.State.CANCEL){
            //已经处理过一次
            return  true;
        }

        //回滚数据 恢复可用余额
        accountMapper.refund(accountFreeze.getUserId(),accountFreeze.getFreezeMoney()) ;
        //不能直接将表中数据删掉，因为空回滚及业务悬挂需要根据记录判断
        accountFreeze.setFreezeMoney(0);
        accountFreeze.setState(AccountFreeze.State.CANCEL);
        //修改操作
        accountFreezeMapper.updateById(accountFreeze) ;
        return false;
    }
}
